home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 051-075 / disk_075 / comm / comm.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  40KB  |  1,287 lines

  1. /*    Comm 1.34 -- The Communicator -- a terminal program for Amiga */
  2.  
  3. /*
  4.          This program is placed in the public domain is freely
  5.          distributable and is intended for personal use only.
  6.          Sale of this program except for REASONABLE media costs
  7.          is prohibited.
  8. */
  9.  
  10. #define  COMM 1
  11. #define  RXCRLF  0xFF00
  12. #define  TXCRLF  0x00FF
  13.  
  14. #include "globals.h"
  15. #include <fcntl.h>
  16. #include <workbench/startup.h>
  17. #include <workbench/workbench.h>
  18. #include <workbench/icon.h>
  19.  
  20. #define CREATE  O_WRONLY | O_CREAT | O_TRUNC
  21.  
  22. extern USHORT Read_RS();
  23. extern int    init_serial(), Open_Timer(), Close_Timer(), Split_Window(),
  24.               MyCloseWindow();
  25. extern UBYTE  toasc(), *get_phnum(), *malloc(), *MyOpenWindow(),
  26.               *OpenLibrary();
  27. extern void   dial(), Init_phone_lib(), list_plib(), Single_Window(), InitMenu(),
  28.               emit_tx(), emits_tx(), emit_rx(), emits_rx(), InitReq(),
  29.               hang_up();
  30. extern struct MenuItem *ItemAddress();
  31. extern struct IntuiMessage *GetMsg();
  32. extern struct Window *OpenWindow();
  33. extern struct Screen *OpenScreen();
  34. extern struct Task   *FindTask();
  35.  
  36. int    KeepGoing, capture, send, ph_nums, menu_event, tranr, bcount, gotxon,
  37.        close_view = FALSE, scrnpos = 13, prefbaud;
  38. char   name[MAXFNAME],  strbuff[ MAXFNAME + 41 ], *number, c;
  39. FILE   *trans;
  40. ULONG  sdelay = 0, IconBase = 0;
  41.  
  42.  
  43. static int  lcnt = 0;      /* ascii debug character counter */
  44. static char line[17];      /* ascii debug line buffer */
  45. static APTR err_window;
  46.  
  47. static int timeron= FALSE; /* true if timer device opened */
  48. USHORT tmpchopflg = FALSE; /* hold state of chopflg during XMODEM recv. */
  49. USHORT eolflg     = 0;
  50.  
  51. #define C_OFF 0
  52. #define C_ON  1
  53. #define C_SUS 2
  54. UBYTE  *stat[] = {(UBYTE *)"   ",(UBYTE *)"ON ",(UBYTE *)"SUS"};
  55. struct View          *View          = NULL;
  56. struct ViewPort      *ViewPort      = NULL, *ViewPortAddress();
  57.  
  58. /******************************************************/
  59. /*                   Main Program                     */
  60. /*                                                    */
  61. /*      This is the main body of the program.         */
  62. /******************************************************/
  63.  
  64. main(argc,argv)
  65. int argc;
  66. char **argv;
  67. {
  68.   void   help(), decode_raw_key(), Process_tx_event(), Process_rx_event();
  69.   void   Process_rq_event(), Process_vw_event(), InitSystem(), Process_menu_event();
  70.   void   Process_screen_item(), Process_baud_rate();
  71.  
  72.   SetTaskPri(FindTask(0L),install.priority);/* bump our priority a little */
  73.  
  74.   InitSystem(argc,argv);            /* Open windows and devices */
  75.   InitMenus();                      /* init. menus */
  76.   Init_phone_lib();                 /* initialize phone library  */
  77.   SetMenuStrip(tx_window,menu);     /* attach menus to tx window */
  78.  
  79.   KeepGoing = gotxon = TRUE;
  80.   close_window = send = capture = FALSE;
  81.   trans = NULL; tranr = NULL;
  82.   DeActivate(&Dirgadget);
  83.  
  84.   ph_nums = load_plib(phonedir);    /* load the phone library */
  85.  
  86.   if(Init_keymacros()==NULL)        /* and the key macro file */
  87.   {
  88.       sprintf(sbuff,"Can't open key file %s\n",commkeys);
  89.       emits_rx(sbuff);
  90.   }
  91.   menu_event = NULL;                /* no menu items selected */
  92.   BeginIO(Read_Request);            /* ready serial input */
  93.   if(install.prefbaud)
  94.     Process_baud_rate( prefbaud );  /* adjust baud rate */
  95.   Modem_init();                     /* send init string to modem */
  96.   Xon(xonflg);                      /* enable XON/XOFF protocol if selected */
  97.   *name = NULL;
  98.   capt_status = stat[ C_OFF ];
  99.  
  100.   while( KeepGoing )                /* the big loop */
  101.   {
  102.      if (send && gotxon)            /* if we are in ASCII send mode and enabled */
  103.      {
  104.          if ((c = getc(trans)) != EOF)      /* get a byte from the file */
  105.          {
  106.              Delay(sdelay);                 /* slider delay */
  107.              if( c == '\n')
  108.                  OutChar('\r');             /* if LF, send CR */
  109.              else if( c != '\r') OutChar(c);
  110.          }
  111.          else
  112.          {
  113.             fclose(trans);                /* here at end of file */
  114.             emits_rx("\nFile Sent\n");
  115.             send = FALSE;                 /* turn off send flag */
  116.             Swap_capture(ASCSEND,START);  /* normal menu entry */
  117.           }
  118.      }
  119.      else
  120.    /* wait for requester, serial port or other windows message */
  121.  
  122.      Wait((1L << Read_Request->IOSer.io_Message.mn_ReplyPort->mp_SigBit)
  123.         | (1L << tx_window->UserPort->mp_SigBit));
  124.  
  125.      Process_window_event();
  126.      while(CheckIO(Read_Request))     /* any serial activity? */
  127.      {
  128.          Process_serial_chars();
  129.          BeginIO(Read_Request);
  130.          Process_window_event();
  131.      }
  132.   }  /* end while ( keepgoing ) */
  133.  
  134. /*   It must be time to quit, so we have to clean
  135. *   up and exit.
  136. */
  137.    if(capture)
  138.    {
  139.       flush();                /* flush capture buffer */
  140.       close(tranr);
  141.    }
  142.    if(prt)
  143.       close(prt);             /* release printer */
  144.  
  145.    clean_up(0L);              /* shut everything down */
  146.    exit( 1 );
  147. } /* end of main */
  148.  
  149. /*************************************************************
  150.    Get and process characters from the serial device.  Characters are found
  151.    in array rs_in.  Serlen contains the number of characters in the buffer.
  152. */
  153. Process_serial_chars()
  154. {
  155.    USHORT bfcnt, i, serlen;
  156.    UBYTE  dispbuf[ RSBUFSIZ * 2 ];
  157.  
  158.    serlen = Read_RS();
  159.    for(bfcnt = i = 0; i < serlen; i++)
  160.    {
  161.      if(rs_in[i] == NULL) continue;
  162.  
  163.      if(debug & NOMASK)       /* strip parity? */
  164.        c = rs_in[i];          /* no */
  165.      else
  166.        c = rs_in[i] & 0x7f;   /* yes */
  167.  
  168.        if (capture && capton)       /* capturing data to disk file? */
  169.          if (isprint(c)) buffer_it(c);
  170.          else
  171.             switch(c)      /* only allow some control chars in file */
  172.             {
  173.                case '\n':
  174. /*             case '\r':     */
  175.                case '\t':
  176.                           buffer_it(c);
  177.             }
  178.        if(debug & SHOWHEX)       /* Show HEX character? */
  179.        {
  180.          sprintf(sbuff,"%02.2x ",c);    /* print HEX digit pair */
  181.          emits_rx(sbuff);
  182.  
  183.          line[lcnt++] = (isprint(c) ? c : '.'); /* buffer ASCII */
  184.          if(lcnt > 16)                  /* until 16 HEX chars */
  185.          {
  186.            line[lcnt] = NULL;
  187.            emits_rx("   ");  /* dump ASCII debug buffer */
  188.            emits_rx(line);
  189.            emit_rx('\n');
  190.            lcnt = 0;
  191.          }
  192.        }
  193.        else                /* not showing HEX characters */
  194.          switch (c)        /* filter out control chars. */
  195.          {
  196.            case XON:
  197.                      gotxon = TRUE;  break;
  198.            case XOFF:
  199.                      gotxon = FALSE; break;
  200.            case 7:        /* except BELL   */
  201.                     Beep(); break;
  202.            case '\r':     /*   "    CR     */
  203.                       if(eolflg & RXCRLF)
  204.                       {
  205.                            c = '\n';
  206.                            dispbuf[bfcnt++] = '\r';
  207.                       }
  208.            case 8:        /*   BACKSPACE   */
  209.            case 9:        /*   "    TAB    */
  210.            case '\n':     /*   " NEWLINE   */
  211.            case '\f':     /*   " FORM FEED */
  212.            case 0x1b:     /*   "    ESC    */
  213.                     dispbuf[bfcnt++] = c;
  214.                     break;
  215.            default:   if(isprint(c))
  216.                         dispbuf[bfcnt++] = c;
  217.                       break;
  218.         }
  219.     }
  220.     dispbuf[bfcnt] = NULL;         /* end buffer with a NULL */
  221.     if((debug & SHOWHEX) == 0)
  222.        emits_rx(dispbuf);          /* print string to screen */
  223.  
  224.     doprint(dispbuf,bfcnt);        /* and to printer (if on) */
  225. }
  226.  
  227. /* print a string on the printer */
  228. doprint(addr,cnt)
  229. UBYTE *addr;
  230. int   cnt;
  231. {
  232.    UBYTE *buff;
  233.    int   tmp;
  234.  
  235.    if(printon != TRUE)           /* if not selected, return */
  236.       return;
  237.  
  238.    buff = addr;
  239.    tmp = cnt;
  240.  
  241.    while(tmp--)
  242.    {
  243.      if(*addr == 8)              /* BACKSPACE? */
  244.         *addr = 0x7F;            /* make it DELETE */
  245.      if(isprintable(*addr))
  246.      {
  247.         addr++;
  248.         continue;
  249.      }
  250.      else
  251.         *addr++ = NULL;          /* zap out unprintable characters */
  252.      }
  253.  
  254.      if(write(prt,buff,cnt) != cnt)
  255.      {
  256.          printon = FALSE;
  257.          close(prt);  Beep();
  258.          emits_rx("\n\nERROR writing to printer -- print aborted\n");
  259.      }
  260. }
  261.  
  262. /* determine what is and isn't printable on the printer */
  263. isprintable(ch)
  264. UBYTE ch;
  265. {
  266.    ch &= 0x7F;
  267.  
  268.    if(isprint(ch))         /* I allow all alphanumerics */
  269.       return TRUE;
  270.    switch(ch)              /* and these control characters */
  271.    {
  272.       case 10: case 13: case 9: case 7: case 8: case 0x7F:
  273.                return TRUE;
  274.    }
  275.    return FALSE;
  276. }
  277.  
  278. /* an IDCMP port message has been received.  Determine the window it
  279.     came from then process the message
  280. */
  281. Process_window_event()
  282. {
  283.   while( NewMessage = GetMsg(tx_window->UserPort) )
  284.      Process_window_msg( NewMessage );
  285. }
  286.  
  287. Process_window_msg(msg)
  288. struct IntuiMessage *msg;
  289. {
  290.   ULONG  class;
  291.   USHORT code,      qual;
  292.   APTR   address;
  293.   struct Window   *which;           /* which window has an event */
  294.  
  295.     
  296.   class   = msg->Class;
  297.   code    = msg->Code;
  298.   qual    = msg->Qualifier;
  299.   which   = msg->IDCMPWindow;
  300.   address = msg->IAddress;
  301.   ReplyMsg( msg );
  302.  
  303.   if(class == RAWKEY || class == MENUPICK)
  304.       Process_tx_event( (long)class, code, qual, address);
  305.   else if(which == tx_window)
  306.       Process_tx_event( (long)class, code, qual, address);
  307.   else if(which == vw_window)
  308.       Process_vw_event( (long)class, code, qual);
  309.   else if(which == req_window)
  310.       Process_rq_event( (long)class, address);
  311.   else if(which == rx_window)
  312.       Process_rx_event( (long)class, code, qual, address);
  313.   else if(which == st_window)
  314.       {
  315.          if(address == &delay_prop)
  316.             sdelay = ((ULONG)propinfo.HorizPot >> 12);
  317.          else
  318.          {
  319.             while( msg = GetMsg(st_window->UserPort) )  ReplyMsg(msg);
  320.             ClearMenuStrip(st_window);
  321.             MyCloseWindow(st_window);
  322.             st_window = NULL;
  323.          }
  324.       }
  325.   if(close_window)
  326.   {
  327.     Single_Window();
  328.     SysItems[0].Flags &= ~CHECKED; /* turn off check mark in menu */
  329.   }
  330.   if(close_view)
  331.   {
  332.     if((close_view = MyCloseWindow(vw_window)) == FALSE)
  333.        vw_window = NULL;
  334.   }
  335. }
  336. /************************************************************************
  337.    Some event happened in the rx window.  Process only the events we are
  338.    interested in.
  339. */
  340. void Process_rx_event( class, code, qual, address)
  341. ULONG  class;
  342. USHORT code, qual;
  343. APTR   address;
  344. {
  345.      Process_tx_event( class, code, qual, address);
  346. }
  347.  
  348.  
  349. /**************************************************************************
  350.    Some event happened in the tx window.  Process events we are interested
  351.    in.
  352. */
  353. void Process_tx_event( class, code, qual, address )
  354. ULONG  class;
  355. USHORT code, qual;
  356. APTR   address;
  357. {
  358.   USHORT itemnum, menunum, subnum;
  359.   struct MenuItem *Item;
  360.   void   Process_menu_item();
  361.  
  362.   if(address == &tx_window_close)
  363.       KeepGoing = FALSE;
  364.   else if(address == &tx_window_front)
  365.        {
  366.           if(vw_window)
  367.              WindowToFront(vw_window);
  368.        }
  369.   else if(address == &tx_window_back)
  370.       ScreenToBack(commscreen);
  371.   else if(address == &rx_window_close)
  372.       close_window = TRUE;
  373.   else if(address == &rx_window_front)
  374.        {
  375.          WindowToBack(tx_window);
  376.          WindowToBack(rx_window);
  377.        }
  378.   else if(address == &rx_window_back)
  379.       ScreenToBack(commscreen);
  380.   else
  381.   switch( class )
  382.    {
  383.      case CLOSEWINDOW:
  384. /*
  385.      User is ready to quit, so indicate that execution should terminate
  386.      with next iteration of the loop.
  387. */
  388.           KeepGoing = FALSE;
  389.           break;
  390.  
  391.      case RAWKEY:
  392.    /*  User has touched the keyboard */
  393.           switch( code )
  394.             {
  395.                case 69: /* escape key */
  396.                         abort = TRUE;
  397.                default:
  398.                      c = toasc(code,qual); /* get in into ascii */
  399.                      decode_raw_key( c );
  400.                      break;
  401.             }
  402.           break;
  403.  
  404.      case MENUPICK:
  405.    /* we had a menu selection. */
  406.                    while ( code != MENUNULL )
  407.                    {
  408.                       menunum = MENUNUM( code );
  409.                       itemnum = ITEMNUM( code );
  410.                       subnum  = SUBNUM(  code );
  411.                       Process_menu_item( menunum, itemnum , subnum);
  412.                       Item = ItemAddress( &menu[0], (long)code );
  413.                       code = Item->NextSelect;
  414.                    }
  415.                    break;
  416.    }   /* end of switch (class) */
  417. }
  418. /*
  419.    View window was closed
  420. */
  421. void Process_vw_event( class, code, qual )
  422. ULONG  class;
  423. USHORT code, qual;
  424. {
  425.      if( class == CLOSEWINDOW)
  426.      {
  427.          viewflg = FALSE;
  428.          SysItems[1].Flags &= ~CHECKED;
  429.          close_view = TRUE;
  430.      }
  431. }
  432.  
  433. /*
  434.    Return was hit on string gadget
  435. */
  436. void Process_rq_event( class, address )
  437. ULONG  class;
  438. APTR   address;
  439. {
  440.    struct IntuiMessage *msg;
  441.    UBYTE ch;
  442. /*
  443.    User just hit return in the string input requester.  menu_event was
  444.    set by process_tx_event() when the user selected the file transfer
  445.    type.  Now we have the filename he entered, so go do the file xfer.
  446. */
  447.    if(address == &Dirgadget)
  448.    {
  449.       ch = install.def_dir[ strlen(install.def_dir) -1 ];
  450.       if(ch != ':' && ch != '/')
  451.          strcat(install.def_dir,"/");
  452.       if(dos_version == DOS12)
  453.          ActivateGadget(&Strgadget,req_window,0L);
  454.       return;
  455.    }
  456.    while( msg = GetMsg(req_window->UserPort) )  ReplyMsg(msg);
  457.  
  458. #ifdef ORIGINALCODE    /* Following code is bogus (fnf) */
  459.    req_window = (struct Window *)MyCloseWindow(req_window);
  460. #else
  461.    (void) MyCloseWindow(req_window);
  462.    req_window = NULL;
  463. #endif
  464.    if( (address == &Strgadget) || (address == &OKgadget) )
  465.       Process_menu_event( menu_event );
  466.    else menu_event = NULL;
  467. }
  468.  
  469. /**************************************************************************
  470.    User hit HELP key, print any helpful information.
  471. */
  472. void help()
  473. {
  474.   int i;
  475.  
  476.   for(i = 0; i < KEYMACS; i++)
  477.    if(keymacro[i])
  478.     {
  479.       sprintf(sbuff,"\n%c%d: ",(i > 9) ? 'S' : 'F',(i > 9) ? i-9 : i + 1);
  480.       emits_rx(sbuff);
  481.       emits_rx(keymacro[i]);
  482.     }
  483.   emit_rx('\n');
  484. }
  485.  
  486. /*************************************************************************
  487.       Decode and act upon any special function keys here.  Default action
  488.       is to send the key out the serial port.
  489. */
  490. void decode_raw_key( c )
  491. char c;
  492. {
  493.    char  ch;
  494.  
  495.    switch(c & 0xff)        /* c should be unsigned */
  496.    {
  497.       case NULL:  break;
  498.       case FN1: case FN2: case FN3: case FN4: case FN5:
  499.       case FN6: case FN7: case FN8: case FN9: case F10:
  500.       case SF1: case SF2: case SF3: case SF4: case SF5:
  501.       case SF6: case SF7: case SF8: case SF9: case S10:
  502.                  expand_macro( c );
  503.                  break;
  504.  
  505.       case SHH:  help();          /* and list macros */
  506.                  break;
  507.       case HLP:  if(st_window)
  508.                  {
  509.                     ClearMenuStrip(st_window);
  510.                     MyCloseWindow(st_window);
  511.                     st_window = NULL;
  512.                  }
  513.                  else
  514.                     Show_Status();   /* show status */
  515.                  break;
  516.  
  517.       case XON:  Start_line();   gotxon = TRUE;
  518.                  break;
  519.  
  520.       case TOGSCR:
  521.                  MoveScreen(commscreen,0L,(long)scrnpos);
  522.                  scrnpos *= -1;
  523.                  break;
  524.       case TOGCAP:
  525.                  if(capture)             /* if its on, turn it off */
  526.                  {
  527.                     capton = !capton;
  528.                     if(capton)
  529.                        capt_status = stat[C_ON];
  530.                     else
  531.                        capt_status = stat[C_SUS];
  532.                     status_line(75,capt_status);
  533.                   }
  534.                   else            /* open default file */
  535.                   {
  536.                      if((tranr = open(install.cap_name,CREATE)) == ERROR)
  537.                      {
  538.                         sprintf(sbuff,"\007\nERROR opening %s\n",install.cap_name);
  539.                         emits_rx(sbuff);
  540.                      }
  541.                      else
  542.                      {
  543.                         capton = capture = TRUE;
  544.                         bcount = 0;
  545.                         Swap_capture(ASCCAPT,capture != TRUE);
  546.                         sprintf(sbuff,"\007\nDefault CAPTURE file %s opened\n",install.cap_name);
  547.                         emits_rx(sbuff);
  548.                         capt_status = stat[C_ON];
  549.                         status_line(75,capt_status);
  550.                      }
  551.                   }
  552.                   RefreshStatus();
  553.                   break;
  554.  
  555.         case TOGPRT:
  556.                      if(printon)            /* if printer was on */
  557.                      {
  558.                         ch = 13;
  559.                         doprint(&ch,1);     /* print a CR to clear buffer */
  560.                         close(prt);
  561.                         printon = FALSE;
  562.                         prt = NULL;
  563.                      }
  564.                      else
  565.                      {
  566.                         if((prt = open("PRT:",O_WRONLY)) == -1)
  567.                         {
  568.                            Beep();
  569.                            emits_rx("\n\nERROR opening printer\n");
  570.                            break;
  571.                         }
  572.                         printon = TRUE;
  573.                      }
  574.                      RefreshStatus();
  575.                      break;
  576. /* wasn't a special key, so send it out the serial port */
  577.         default:
  578.                    OutChar(c);
  579.      }
  580. }
  581.  
  582. /* send a character out to the modem.  Process \r and \n here
  583. */
  584. OutChar(ch)
  585. UBYTE ch;
  586. {
  587.    rs_out[0] = ch;
  588.    DoIO(Write_Request);
  589.    if( ch == '\r' )
  590.    {
  591.       if( eolflg & TXCRLF )
  592.          OutChar('\n');
  593.    }
  594.    if(halfduplex & !split_screen)
  595.       emit_rx(ch);
  596.    if(split_screen)
  597.    {
  598.       if(ch == '\r')     /* make CR into LF for */
  599.         emit_tx('\n');  /* readability & scrolling */
  600.       else if(ch == 8)
  601.          emits_tx("\010 \010");  /* destructive BACKSPACE */
  602.       else  if(ch == 7)
  603.                Beep();
  604.       else  emit_tx(ch);
  605.    }
  606. }
  607.  
  608. /**************************************************************************
  609.    Process user selected menu item.  menuitem and itemnum were determined
  610.    by process_tx_event()
  611. */
  612. void Process_menu_item( menunum, itemnum, subnum)
  613. USHORT   menunum, itemnum, subnum;
  614. {
  615.   void Process_file_item(), Process_baud_rate(), Process_sys_item();
  616.   void Process_serial_item();
  617.  
  618.   switch( menunum )
  619.     {
  620.        case 0: Process_file_item( itemnum, subnum );    /* FILE transfer */
  621.                break;
  622.        case 1: Process_sys_item( itemnum ,subnum );     /* SYSTEM */
  623.                break;
  624.        case 2: crcflag = xfrmode = itemnum;             /* MODE */
  625.                break;
  626.        case 3: Process_serial_item( itemnum, subnum );  /* SERIAL */
  627.                break;
  628.        case 5: Process_debug_item( itemnum, subnum );   /* DEBUG */
  629.                break;
  630.        case 4:                                          /* PHONE */
  631.                if( itemnum == 1 )  /* alternate long dist serv */
  632.                {
  633.                   altservflg = TRUE;
  634.                   PhoneItem[1].Flags |= CHECKED;
  635.                }
  636.                else if( itemnum == 0 )  /* hang up */
  637.                {
  638.                    hang_up();
  639.                }
  640.                else if( pdir[ itemnum-2 ].number[0] != NULL)
  641.                {/* dial resets altservflg, we reset checkmark */
  642.                    itemnum -= 2;
  643.                    list_plib( itemnum );
  644.                    set_baud(atoi(pdir[ itemnum ].baud));
  645.                    dial(pdir[ itemnum ].number);
  646.                    PhoneItem[1].Flags &= ~CHECKED;
  647.                    if(install.keyload)
  648.                      Load_keymacros(pdir[ itemnum ].name);
  649.                }
  650.                break;
  651.     }
  652. }
  653.  
  654. Process_debug_item(itemnum, subnum)
  655. USHORT itemnum, subnum;
  656. {
  657.    if(debug & (1 << itemnum))   /* if bit is set */
  658.    {
  659.       debug &= ~(1 << itemnum);  /* reset it */
  660.       DebugItems[itemnum].Flags &= ~CHECKED;
  661.    }
  662.    else
  663.    {
  664.       debug |= (1 << itemnum);   /* else, set it */
  665.       DebugItems[itemnum].Flags |= CHECKED;
  666.       lcnt = 0;
  667.    }
  668. }
  669.  
  670. /************************************************************************
  671.    Process the menu event the user desires.  This processing was delayed
  672.    until the user entered a filename using the string input requester.
  673. */
  674. void Process_menu_event( menu_event )
  675. {
  676.   UBYTE fname[ MAXFNAME + 41 ];
  677.   int   temp;
  678.  
  679.   fname[0] = NULL;
  680.   if(index(name,':') == 0)
  681.      strcpy(fname,install.def_dir);
  682.   strcat(fname,name);
  683.  
  684.   *name = NULL;
  685.  
  686.   switch (menu_event)
  687.     {
  688.       case NULL:   break;
  689.       case ASCCAPT:
  690.                    if(file_exists(fname))       /* requested file exists */
  691.                    {
  692.                       if(!use_file(fname))      /* he wants a new one */
  693.                       {
  694.                           menu_event = NULL;
  695.                           strcpy(name,fname);
  696.                           Process_file_item(0,0);
  697.                           break;
  698.                       }
  699.                       else                      /* no: use the old one */
  700.                           if( app_del() )
  701.                               tranr = open(fname,O_WRONLY); /* append data */
  702.                           else
  703.                               tranr = open(fname,CREATE);
  704.                    }
  705.                    else
  706.                      tranr = open(fname,CREATE);
  707.                    if (tranr == ERROR)
  708.                    {
  709.                        capture = capton = FALSE;
  710.                        sprintf(sbuff,"\nError Opening File %s\n",fname);
  711.                        emits_rx(sbuff);
  712.                        break;
  713.                    }
  714.                    capt_status = stat[C_ON];
  715.                    status_line(75,capt_status);
  716.                    capton = capture = TRUE;
  717.                    bcount = 0;
  718.                    RefreshStatus();
  719.                    lseek(tranr,0L,2);
  720.                    break;
  721.       case ASCSEND:
  722.                    if ((trans = fopen(fname,"r")) == 0)
  723.                    {
  724.                      send = FALSE;
  725.                      sprintf(sbuff,"\nError Opening File %s\n",fname);
  726.                      emits_rx(sbuff);
  727.                      break;
  728.                    }
  729.                   sdelay = ((ULONG)propinfo.HorizPot >> 12);
  730.                   send = TRUE;
  731.                   break;
  732.       case WXMRECV:  wxflag = TRUE;
  733.       case XMDRECV:
  734.                     if(file_exists(fname))
  735.                        if(!use_file(fname))
  736.                        {
  737.                            menu_event = NULL;
  738.                            Process_file_item(2,0);
  739.                            break;
  740.                         }
  741.                     Set_Menus(OFF);         /* Ghost the menus */
  742.                     if(test_4_arc(fname))   /* turn off auto chopping for */
  743.                        chopflg = FALSE;     /* .ARC files */
  744.                     if(viewflg) WindowToFront(vw_window);
  745.                     if (XMODEM_Read_File(fname))
  746.                         emits_rx("\nReceived File\n");
  747.                     else
  748.                       {
  749.                         close(fd);
  750.                         emits_rx("\nXmodem Receive Failed\n");
  751.                       }
  752.                      clear_status_line(); status_line(75,capt_status);
  753.                      Set_Menus(ON);
  754.                      Beep();
  755.                      Xconfig(FALSE);  wxflag = FALSE;
  756.                      chopflg = tmpchopflg;   /* restore CHOP mode flag */
  757.                      if(abort)
  758.                         emits_rx("User aborted transfer\n");
  759.                      break;
  760.       case XMDSEND:
  761.                      if(!file_exists(fname))
  762.                      {
  763.                         no_file();         /* No such file requester */
  764.                         menu_event = NULL;
  765.                         Process_file_item(4,0); /* get another name */
  766.                         break;
  767.                      }
  768.                      Set_Menus(OFF);
  769.                      if(viewflg) WindowToFront(vw_window);
  770.                      if (XMODEM_Send_File(fname))
  771.                          emits_rx("\nFile Sent\n");
  772.                      else
  773.                        {
  774.                          close(fd);
  775.                          emits_rx("\nXmodem Send Failed\n");
  776.                        }
  777.                      clear_status_line(); status_line(75,capt_status);
  778.                      Set_Menus(ON);
  779.                      Beep();
  780.                      Xconfig(FALSE);
  781.                      asciiflg = FALSE;
  782.                      if(abort)
  783.                         emits_rx("User aborted transfer\n");
  784.                      break;
  785.       case EDITMAC:  Add_keymacro();
  786.                      break;
  787.       case LOADPHONE:temp = load_plib(strbuff);
  788.                      if(temp)
  789.                         ph_nums = temp;
  790.                      break;
  791.       case LOADKEYS: Load_keymacros(strbuff);
  792.                      break;
  793.       case SAVEKEYS: Save_keymacros(strbuff);
  794.                      break;
  795.     }
  796.   Swap_capture(ASCCAPT,capture != TRUE);
  797.   Swap_capture(ASCSEND,send    != TRUE);
  798.   menu_event = NULL;
  799. }
  800.  
  801. /************************************************************************/
  802. void Process_file_item( itemnum, subnum )
  803. USHORT itemnum, subnum;
  804. {
  805.   Activate(&Dirgadget);
  806.   crcflag = xfrmode;    /* restore selected xfer mode */
  807.   switch( itemnum )
  808.   {
  809.        case 0:
  810.                if (capture == TRUE)
  811.                  {
  812.                    capton = capture = FALSE;
  813.                    flush();
  814.                    close(tranr);
  815.                    emits_rx("\nEnd File Capture\n");
  816.                    Swap_capture(ASCCAPT,START);
  817.                    capt_status = stat[C_OFF];
  818.                    status_line(75,capt_status);  /* remove ON/SUS on screen */
  819.                  }
  820.                else
  821.                    if(getfile("Ascii Capture filename",name))
  822.                       Process_menu_event( ASCCAPT );
  823.                      RefreshStatus();
  824.                break;
  825.        case 1:
  826.                if (send == TRUE)
  827.                {
  828.                  send = FALSE;
  829.                  fclose(trans);
  830.                  Xon(xonflg);
  831.                  emits_rx("\nFile Send Canceled\n");
  832.                  Swap_capture(ASCSEND,START);
  833.                }
  834.                else
  835.                    if(getfile("Ascii Send filename",name))
  836.                       Process_menu_event( ASCSEND );
  837.                break;
  838.        case 2:
  839.                tmpchopflg = chopflg;
  840.                if(getfile("Xmodem Receive filename",name))
  841.                   Process_menu_event( XMDRECV );
  842.                break;
  843.        case 3:
  844.                tmpchopflg = chopflg;
  845.                if(getfile("WXmodem Receive filename",name))
  846.                  Process_menu_event( WXMRECV );
  847.                break;
  848.        case 5:
  849.                asciiflg = TRUE;
  850.        case 4:
  851.                if(getfile("Xmodem Send filename",name))
  852.                  Process_menu_event( XMDSEND );
  853.                else asciiflg = FALSE;
  854.                break;
  855.        case 6: KeepGoing = FALSE;
  856.                break;
  857.              }
  858. }
  859.  
  860. #define FLUSH (-2)
  861.  
  862. buffer_it(ch)
  863. int ch;
  864. {
  865.    if( ((ch == FLUSH) && bcount) || (bcount == BufSize) )
  866.    {                                /* write any data in the buffer */
  867.      if(write(tranr,buffer,bcount) != bcount)
  868.      {
  869.          emits_rx("ERROR writing to file.  File closed\n");
  870.          close(tranr);
  871.          capton = capture = FALSE;
  872.      }
  873.      bcount = 0;
  874.    }
  875.    buffer[ bcount++ ] = ch;          /* buffer the character */
  876. }
  877.  
  878. flush()
  879. {
  880.    buffer_it( FLUSH );
  881. }
  882.  
  883. /************************************************************************
  884.    set serial port to desired baud rate
  885. */
  886. void Process_baud_rate( itemnum )
  887. USHORT itemnum;
  888. {
  889.    int baudrate;
  890.  
  891.    switch( itemnum )
  892.      {
  893.         case 0: baudrate = 300;   break;
  894.         case 1: baudrate = 1200;  break;
  895.         case 2: baudrate = 2400;  break;
  896.         case 3: baudrate = 4800;  break;
  897.         case 4: baudrate = 9600;  break;
  898.         case 5: baudrate = 19200; break;
  899.         default: return;
  900.      }
  901.      set_baud( baudrate );
  902. }
  903.  
  904. /*************************************************************************
  905.    process system menu selection.
  906. */
  907. void Process_sys_item( itemnum, subnum )
  908. USHORT itemnum, subnum;
  909. {
  910.    UBYTE temp[80];
  911.  
  912.    DeActivate(&Dirgadget);
  913.    menu_event = NULL;
  914.  
  915.    switch ( itemnum )
  916.       {
  917.          case 0:
  918.                   if(split_screen)
  919.                   {
  920.                      Single_Window();
  921.                      SysItems[0].Flags &= ~CHECKED;
  922.                   }
  923.                   else
  924.                   {
  925.                        if( Split_Window() )
  926.                          split_screen = TRUE;
  927.                   }
  928.                   break;
  929.          case 1:
  930.                     if(viewflg)    /* if view window open, close it */
  931.                     {
  932.                        viewflg = FALSE;
  933.                        SysItems[1].Flags &= ~CHECKED;
  934.                        close_view = TRUE;
  935.                     }
  936.                   else    /* else open view window */
  937.                     {
  938.                       viewflg = TRUE;
  939.                       if( ( vw_window = (struct Window *)
  940.                          MyOpenWindow(&VWindow,(ULONG)CLOSEWINDOW | GADGETUP)) == NULL)
  941.                          {
  942.                            emits_rx("Can't open view window\n");
  943.                            viewflg = FALSE;
  944.                          }
  945.                       else
  946.                       {
  947.                           vw_con = CreateStdIO(vw_con_mp);
  948.                           open_console(vw_window,vw_con);
  949.                           WindowToFront(vw_window);
  950.                       }
  951.                     }
  952.                   break;
  953.          case 2:
  954.                   if(chopflg)    /* fix the chop mode checkmark to match */
  955.                      SysItems[2].Flags &= ~CHECKED;  /* the mode desired */
  956.                   else
  957.                      SysItems[2].Flags |=  CHECKED;
  958.                   chopflg = !chopflg;
  959.                   break;
  960.          case 3:
  961.                   switch(subnum)
  962.                   {
  963.                      case 0:  eolflg &=  RXCRLF; break;
  964.                      case 1:  eolflg |= ~RXCRLF; break;
  965.                      case 2:  eolflg &=  TXCRLF; break;
  966.                      case 3:  eolflg |= ~TXCRLF; break;
  967.                   }
  968.                   break;
  969.          case 4:
  970.                   switch(subnum)
  971.                   {
  972.                      case 0:  strcpy(strbuff,commkeys);
  973.                               if(getstring("LOAD","Key macro file",strbuff,MAXFNAME)== FALSE)
  974.                                  break;
  975.                               menu_event = LOADKEYS;
  976.                               strcpy(commkeys,strbuff);
  977.                               break;
  978.                      case 1:  strcpy(strbuff,commkeys);
  979.                               if(getstring("SAVE","Key macro file",strbuff,MAXFNAME)==FALSE)
  980.                                  break;
  981.                               menu_event = SAVEKEYS;
  982.                               strcpy(commkeys,strbuff);
  983.                               break;
  984.                      case 2:
  985.                               Edit_keymacro();
  986.                               menu_event = EDITMAC;
  987.                               break;
  988.                  }
  989.                  break;
  990.          case 5:
  991.                  switch(subnum)
  992.                  {
  993.                     case 0:  strcpy(strbuff,phonedir);
  994.                              if(getstring("LOAD","Phone library",strbuff,MAXFNAME)== FALSE)
  995.                                 break;
  996.                              menu_event = LOADPHONE;
  997.                              strcpy(phonedir,strbuff);
  998.                              break;
  999.                     case 1:             /* no SAVE option yet */
  1000.                              break;
  1001.                     case 2:
  1002.                              strcpy(temp,"C:ED          ");
  1003.                              strcat(temp,phonedir);
  1004.                              WBenchToFront();
  1005.                              ShowTitle(commscreen,1L);
  1006.                              Execute(temp,0L,0L);
  1007.                              ShowTitle(commscreen,install.titlebar);
  1008.                              WBenchToBack();
  1009.                              break;
  1010.                  }
  1011.                  break;
  1012.          case 6:     /* title bar */
  1013.                  install.titlebar = (long)subnum;
  1014.                  ShowTitle(commscreen,install.titlebar);
  1015.                  break;
  1016.          }
  1017. }
  1018.  
  1019. DeActivate(gadg)
  1020. struct Gadget *gadg;
  1021. {
  1022.    gadg->Flags |= GADGDISABLED;
  1023. }
  1024.  
  1025. Activate(gadg)
  1026. struct Gadget *gadg;
  1027. {
  1028.    gadg->Flags &= ~GADGDISABLED;
  1029. }
  1030.  
  1031.  
  1032. /************************************************************************/
  1033. void Process_serial_item( itemnum, subnum )
  1034. USHORT itemnum, subnum;
  1035. {
  1036.    switch( itemnum )
  1037.      {
  1038.         case 0:
  1039.                   Process_baud_rate( subnum );    /* BAUD rate */
  1040.                   break;
  1041.         case 1:   Setparity( subnum );            /* parity */
  1042.                   break;
  1043.         case 2:   Setlength( subnum );            /* word length */
  1044.                   break;
  1045.         case 3:   Setstopbits( subnum );          /* stop bits */
  1046.                   break;
  1047.         case 4:   halfduplex = subnum;            /* duplex */
  1048.                   break;
  1049.         case 5:   xonflg = subnum;                /* XON/XOFF */
  1050.                   Xon(xonflg);
  1051.                   break;
  1052.         case 6:   SendBreak();                    /* send break */
  1053.                   break;
  1054.      }
  1055. }
  1056.  
  1057. /**************************************************************************
  1058.    Initialize the system.  Open windows, libraries and devices.  Exit
  1059.    cleanly if any trouble intializing.
  1060. */
  1061. void InitSystem(argc,argv)
  1062. int argc;
  1063. UBYTE **argv;
  1064. {
  1065.   struct WBArg *wbarg;
  1066.   struct DiskObject *diskobj, *GetDiskObject();
  1067.   struct WBStartup *wb_msg;
  1068.   struct Library   *DOSbase;
  1069.   struct Preferences Pref;
  1070.  
  1071.   int    i,args;
  1072.   char  *ttype, *FindToolType();
  1073.   UBYTE *temp;
  1074.  
  1075.   DOSbase = (struct Library *)OpenLibrary(DOSNAME,0L);
  1076.   if(DOSbase)
  1077.     dos_version = DOSbase->lh_Version;
  1078.  
  1079.   IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",(long)dos_version);
  1080.   if( IntuitionBase == NULL )
  1081.      clean_up("Can't open intuition library\n");
  1082.  
  1083.   GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",(long)dos_version);
  1084.   if( GfxBase == NULL )
  1085.      clean_up("Can't open graphics library\n");
  1086.  
  1087.   args = argc;
  1088.  
  1089.   if(argc == 0)                     /* called from WorkBench */
  1090.   {
  1091.     if((IconBase = (ULONG)OpenLibrary(ICONNAME,0L)) == NULL)
  1092.        clean_up("Can't open Icon library\n");
  1093.  
  1094.     PlibItems[ 2 ].Flags &= ~ITEMENABLED;  /* can't use ED */
  1095.     wb_msg = (struct WBStartup *)argv;
  1096.     wbarg = wb_msg->sm_ArgList;
  1097.  
  1098.     diskobj = GetDiskObject(wbarg->wa_Name);
  1099.     if( diskobj != NULL )        /* get default files from .info file */
  1100.     {
  1101.        ttype = NULL;
  1102.        ttype = FindToolType(diskobj->do_ToolTypes,"PHONE");
  1103.        if(ttype)
  1104.          strcpy(phonedir,ttype);
  1105.        ttype = FindToolType(diskobj->do_ToolTypes,"KEYS");
  1106.        if(ttype)
  1107.          strcpy(commkeys,ttype);
  1108.        ttype = FindToolType(diskobj->do_ToolTypes,"INTERLACE");
  1109.          install.interlace = (strcmp(ttype,"ON") == 0);
  1110.        FreeDiskObject( diskobj );
  1111.     }
  1112.   }
  1113.   else
  1114.   {
  1115.     Defdir();                       /* find default directory */
  1116.  
  1117.     for(i = 1; i < argc; i++)
  1118.     {
  1119.        temp = argv[ i ];
  1120.        if(*temp++ == '-')
  1121.        {
  1122.           args--;
  1123.           while(*temp == 'i' || *temp == 'I')
  1124.           {
  1125.              install.interlace = TRUE; temp++;
  1126.           }
  1127.        }
  1128.        else
  1129.           strcat(phonedir,argv[ i ]);
  1130.     }
  1131.   }
  1132.  
  1133.   if(*phonedir == NULL)  strcpy(phonedir,PHONELIB);
  1134.  
  1135.   if(dos_version == DOS12)
  1136.   {
  1137.      RXWindow.Height    = GfxBase->NormalDisplayRows - 10;
  1138.      RXWindow.MinHeight = GfxBase->NormalDisplayRows - 52;
  1139.      STWindow.TopEdge   = GfxBase->NormalDisplayRows - 10;
  1140.      TXWindow.Height    = GfxBase->NormalDisplayRows - 10;
  1141.      CommScreen.Height  = GfxBase->NormalDisplayRows;
  1142.   }
  1143.   if(install.interlace)
  1144.   {
  1145.      CommScreen.ViewModes |= LACE;
  1146.  
  1147.      CommScreen.Height <<= 1;
  1148.      RXWindow.Height   <<= 1; RXWindow.TopEdge <<= 1; RXWindow.MinHeight <<= 1;
  1149.      STWindow.TopEdge  <<= 1; STWindow.TopEdge +=  8;
  1150.      TXWindow.Height   <<= 1; TXWindow.TopEdge <<= 1; TXWindow.MinHeight <<= 1;
  1151.      VWindow.Height    <<= 1; VWindow.TopEdge  <<= 1; VWindow.MaxHeight  <<= 1;
  1152.   }
  1153.  
  1154. /* allocate disk buffer for XMODEM must have at least 16 buffers */
  1155.   for(numbufs = install.numbuffs; numbufs > 15; numbufs -= 8)
  1156.     if( (diskbuff = malloc( numbufs * SECSIZ)) != NULL)
  1157.       break;
  1158.   if(diskbuff == NULL)
  1159.       clean_up("Can't allocate disk buffers\n");
  1160.  
  1161.   GetPrefs(&Pref,4L);
  1162.  
  1163.   commscreen = OpenScreen(&CommScreen);
  1164.   if(commscreen == 0)
  1165.      clean_up("Can't open screen\n");
  1166.  
  1167.   prefbaud = Pref.BaudRate -1;
  1168.   RXWindow.Screen = STWindow.Screen = TXWindow.Screen = VWindow.Screen =
  1169.       STwindow.Screen = RQWindow.Screen = commscreen;
  1170.  
  1171.   if(( tx_window = OpenWindow(&TXWindow) ) == NULL)
  1172.      clean_up("Can't open window\n");
  1173.  
  1174.   ViewPort = ViewPortAddress(tx_window);
  1175.   if(install.new_colors[0] | install.new_colors[1] | install.new_colors[2]
  1176.    | install.new_colors[3])
  1177.      LoadRGB4(ViewPort,install.new_colors,4L);
  1178.  
  1179.   add_window_gadgets(tx_window);
  1180.   rx_window = tx_window;
  1181.  
  1182.   if(( stat_window = OpenWindow(&STWindow)) == NULL)
  1183.      clean_up("Can't open window\n");
  1184.  
  1185.   ShowTitle(commscreen,0L);
  1186.  
  1187.   if( init_serial() == FALSE)
  1188.      clean_up("Can't open serial device\n");
  1189.   if(Open_Timer())
  1190.       clean_up("Can't open timer device\n");
  1191.   timeron = TRUE;
  1192.   InitBeep();
  1193.  
  1194.   tx_con_mp = CreatePort("tx_con_mp",0L);
  1195.   rx_con_mp = CreatePort("rx_con_mp",0L);
  1196.   st_con_mp = CreatePort("st_con_mp",0L);
  1197.   vw_con_mp = CreatePort("vw_con_mp",0L);
  1198.  
  1199.   tx_con = CreateStdIO(tx_con_mp);
  1200.   rx_con = CreateStdIO(rx_con_mp);
  1201.   st_con = CreateStdIO(st_con_mp);
  1202.  
  1203.   if( open_console(tx_window,tx_con) ||
  1204.       open_console(rx_window,rx_con) ||
  1205.       open_console(stat_window,st_con) )
  1206.         clean_up("Error opening console device\n");
  1207.   clear_status_line();
  1208.  
  1209.   this_process = (struct Process *)FindTask(0L);
  1210.   if(this_process)
  1211.   {
  1212.     err_window = this_process->pr_WindowPtr;
  1213.     this_process->pr_WindowPtr = (APTR)rx_window;
  1214.   }
  1215.   sprintf(sbuff,"\n\t\t\t\t%s\n\n",install.version);
  1216.   emits_rx(sbuff);
  1217. }
  1218.  
  1219. /**********************************************************************/
  1220. clean_up(message)
  1221. char *message;
  1222. {
  1223.   if(message)  puts(message);
  1224.  
  1225.   Modem_exit();         /* send parting string to modem */
  1226.   Close_Beep();         /* close audio...etc. */
  1227.   if( timeron )          Close_Timer();
  1228.   if( diskbuff )         free( diskbuff );
  1229.   Free_keymacros();
  1230.  
  1231.   Close_Serial();       /* close serial and deallocate port and memory */
  1232.  
  1233.   if(rx_con)
  1234.   {
  1235.      close_console(rx_con);  /* close open console device */
  1236.      DeleteStdIO(rx_con);
  1237.   }
  1238.   if(st_con)
  1239.   {
  1240.      close_console(st_con);  /* close open console device */
  1241.      DeleteStdIO(st_con);
  1242.   }
  1243.   if(tx_con)
  1244.   {
  1245.      close_console(tx_con);  /* close open console device */
  1246.      DeleteStdIO(tx_con);
  1247.   }
  1248.   if(vw_con)
  1249.   {
  1250.      close_console(vw_con);  /* close open console device */
  1251.      DeleteStdIO(vw_con);
  1252.   }
  1253.   if(tx_con_mp)     DeletePort(tx_con_mp);
  1254.   if(vw_con_mp)     DeletePort(vw_con_mp);
  1255.   if(rx_con_mp)     DeletePort(rx_con_mp);
  1256.   if(st_con_mp)     DeletePort(st_con_mp);
  1257.  
  1258.   if(this_process)
  1259.     this_process->pr_WindowPtr = err_window;
  1260.  
  1261.   if(req_window)        /* if requester left around, get rid of it */
  1262.      MyCloseWindow( req_window );
  1263.  
  1264. /* close all windows...in order */
  1265.   if(stat_window)        CloseWindow( stat_window );
  1266.   if(st_window)          MyCloseWindow( st_window );
  1267.   if(vw_window )         MyCloseWindow( vw_window );
  1268.   if(split_screen)       MyCloseWindow( rx_window );
  1269.  
  1270.   if(tx_window)
  1271.    {
  1272.      ClearMenuStrip( tx_window );
  1273.      CloseWindow( tx_window );
  1274.    }
  1275.  
  1276.    if(commscreen)
  1277.       CloseScreen(commscreen);
  1278.  
  1279.   if(IntuitionBase)      CloseLibrary(IntuitionBase);
  1280.   if(GfxBase)            CloseLibrary(GfxBase);
  1281.   if(IconBase)           CloseLibrary(IconBase);
  1282.   exit(1);
  1283. }
  1284.  
  1285. /* end of comm 1.34 */
  1286.  
  1287.